#include "netif.h"

static char	netif_hex16charset[] = "0123456789ABCDEF" ;

size_t GetNetInterfaceCount()
{
	size_t		count ;
	struct ifaddrs	*ifa1 = NULL ;
	struct ifaddrs	*ifa = NULL ;
	int		nret = 0 ;
	
	count = 0 ;
	
	nret = getifaddrs( & ifa1 ) ;
	if( nret == -1 )
		return -1;
	
	ifa = ifa1 ;
	while( ifa )
	{
		if( ! (ifa->ifa_flags&IFF_LOOPBACK) )
		{
			if( ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET )
				count++;
		}
		
		ifa = ifa->ifa_next ;
	}
	freeifaddrs( ifa1 );
	
	return count;
}

int GetNetInterfaceIp( size_t idx , uint32_t *ip , char *ip_str_8bytes_and_end_of_1byte , char *ip_str_15bytes_and_end_of_1byte )
{
	size_t		i ;
	struct ifaddrs	*ifa1 = NULL ;
	struct ifaddrs	*ifa = NULL ;
	uint32_t	ipaddr ;
	char		*p_ipaddr = (char*) & ipaddr ;
	int		nret = 0 ;
	
	nret = getifaddrs( & ifa1 ) ;
	if( nret == -1 )
		return -1;
	
	i = 0 ;
	ifa = ifa1 ;
	while( ifa )
	{
		if( ! (ifa->ifa_flags&IFF_LOOPBACK) )
		{
			if( ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET )
			{
				i++;
				
				if( i == idx )
				{
					freeifaddrs( ifa1 );
					
					ipaddr = ((struct sockaddr_in *)(ifa->ifa_addr))->sin_addr.s_addr ;
					
					if( ip )
					{
						(*ip) = ipaddr ;
					}
					
					if( ip_str_8bytes_and_end_of_1byte )
					{
						*(ip_str_8bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(p_ipaddr[0]) >> 4 ] ;
						*(ip_str_8bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(p_ipaddr[0]) & 0x0F ] ;
						*(ip_str_8bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(p_ipaddr[1]) >> 4 ] ;
						*(ip_str_8bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(p_ipaddr[1]) & 0x0F ] ;
						*(ip_str_8bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(p_ipaddr[2]) >> 4 ] ;
						*(ip_str_8bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(p_ipaddr[2]) & 0x0F ] ;
						*(ip_str_8bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(p_ipaddr[3]) >> 4 ] ;
						*(ip_str_8bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(p_ipaddr[3]) & 0x0F ] ;
						*(ip_str_8bytes_and_end_of_1byte++) = '\0' ;
					}
					
					if( ip_str_15bytes_and_end_of_1byte )
					{
						memset( ip_str_15bytes_and_end_of_1byte , 0x00 , 16 );
						snprintf( ip_str_15bytes_and_end_of_1byte , 16 , "%d.%d.%d.%d" , p_ipaddr[0] , p_ipaddr[1] , p_ipaddr[2] , p_ipaddr[3] );
					}
					
					return 0;
				}
			}
		}
		
		ifa = ifa->ifa_next ;
	}
	freeifaddrs( ifa1 );
	
	return 1;
}

int GetNetInterfaceMac( size_t idx , uint64_t *mac , char *mac_str_12bytes_and_end_of_1byte , char *mac_str_17bytes_and_end_of_1byte )
{
	size_t		i ;
	struct ifaddrs	*ifa1 = NULL ;
	struct ifaddrs	*ifa = NULL ;
	struct ifreq	ifr ;
	int		sock ;
	int		nret = 0 ;
	
	nret = getifaddrs( & ifa1 ) ;
	if( nret == -1 )
		return -1;
	
	ifa = ifa1 ;
	i = 0 ;
	while( ifa )
	{
		if( ! (ifa->ifa_flags&IFF_LOOPBACK) )
		{
			if( ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET )
			{
				i++;
				
				if( i == idx )
				{
					memset( & ifr , 0x00 , sizeof(struct ifreq) );
					strncpy( ifr.ifr_name , ifa->ifa_name , sizeof(ifr.ifr_name)-1 );
					sock = socket( AF_INET , SOCK_STREAM , 0 ) ;
					if( sock == -1 )
						return -2;
					
					nret = ioctl( sock , SIOCGIFHWADDR , & ifr ) ;
					if( nret == -1 )
						return -3;
					
					if( mac )
					{
						(*mac) = ifr.ifr_hwaddr.sa_data[0] ;
						(*mac) = ( (*mac) << 8 ) + (unsigned char)(ifr.ifr_hwaddr.sa_data[1]) ;
						(*mac) = ( (*mac) << 8 ) + (unsigned char)(ifr.ifr_hwaddr.sa_data[2]) ;
						(*mac) = ( (*mac) << 8 ) + (unsigned char)(ifr.ifr_hwaddr.sa_data[3]) ;
						(*mac) = ( (*mac) << 8 ) + (unsigned char)(ifr.ifr_hwaddr.sa_data[4]) ;
						(*mac) = ( (*mac) << 8 ) + (unsigned char)(ifr.ifr_hwaddr.sa_data[5]) ;
					}
					
					if( mac_str_12bytes_and_end_of_1byte )
					{
						*(mac_str_12bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[0]) >> 4 ] ;
						*(mac_str_12bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[0]) & 0x0F ] ;
						*(mac_str_12bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[1]) >> 4 ] ;
						*(mac_str_12bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[1]) & 0x0F ] ;
						*(mac_str_12bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[2]) >> 4 ] ;
						*(mac_str_12bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[2]) & 0x0F ] ;
						*(mac_str_12bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[3]) >> 4 ] ;
						*(mac_str_12bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[3]) & 0x0F ] ;
						*(mac_str_12bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[4]) >> 4 ] ;
						*(mac_str_12bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[4]) & 0x0F ] ;
						*(mac_str_12bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[5]) >> 4 ] ;
						*(mac_str_12bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[5]) & 0x0F ] ;
						*(mac_str_12bytes_and_end_of_1byte++) = '\0' ;
					}
					
					if( mac_str_17bytes_and_end_of_1byte )
					{
						(*mac_str_17bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[0]) >> 4 ] ;
						(*mac_str_17bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[0]) & 0x0F ] ;
						(*mac_str_17bytes_and_end_of_1byte++) = ':' ;
						(*mac_str_17bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[1]) >> 4 ] ;
						(*mac_str_17bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[1]) & 0x0F ] ;
						(*mac_str_17bytes_and_end_of_1byte++) = ':' ;
						(*mac_str_17bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[2]) >> 4 ] ;
						(*mac_str_17bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[2]) & 0x0F ] ;
						(*mac_str_17bytes_and_end_of_1byte++) = ':' ;
						(*mac_str_17bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[3]) >> 4 ] ;
						(*mac_str_17bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[3]) & 0x0F ] ;
						(*mac_str_17bytes_and_end_of_1byte++) = ':' ;
						(*mac_str_17bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[4]) >> 4 ] ;
						(*mac_str_17bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[4]) & 0x0F ] ;
						(*mac_str_17bytes_and_end_of_1byte++) = ':' ;
						(*mac_str_17bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[5]) >> 4 ] ;
						(*mac_str_17bytes_and_end_of_1byte++) = netif_hex16charset[ (unsigned char)(ifr.ifr_hwaddr.sa_data[5]) & 0x0F ] ;
						(*mac_str_17bytes_and_end_of_1byte++) = '\0' ;
					}
					
					close( sock );
				}
				
				freeifaddrs( ifa1 );
				
				return 0;
			}
		}
		
		ifa = ifa->ifa_next ;
	}
	freeifaddrs( ifa1 );
	
	return 1;
}

